///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (C) 2007-2009 ILOG, S.A.
//  All Rights Reserved.
//  The following is ILOG Source Code.  No modifications may be made to the  
//  ILOG Source Code.  Any usage of the ILOG Source Code is subject to 
//  the terms and conditions of the ILOG End User License Agreement   
//  applicable to this ILOG software product.
//
///////////////////////////////////////////////////////////////////////////////

package ilog.gauges.controls.black
{
  import ilog.gauges.TickItem;
  import ilog.gauges.gaugesClasses.GaugeElement;
  import ilog.gauges.gaugesClasses.IScale;
  import ilog.gauges.gaugesClasses.circular.ICircularScale;
  import ilog.gauges.gaugesClasses.circular.CircularValueRenderer;
  import ilog.gauges.gaugesClasses.rectangular.IRectangularScale;
  import ilog.gauges.gaugesClasses.rectangular.RectangularValueRenderer;
  
  import mx.core.IDataRenderer;
  import mx.core.UIComponent;
  import mx.events.FlexEvent;
  import mx.skins.ProgrammaticSkin;

  /**
   * A tick renderer for Black gauges which can illuminate or extinguish ticks on the scale
   * according to the gauge value.
   *   
   * @since ILOG Elixir 2.0
   * @ilog.reviewed SH 5 May 08
   */
  public class BlackLightTickRenderer extends ProgrammaticSkin implements IDataRenderer
  {
    /**
     * Constructor.
     */ 
    public function BlackLightTickRenderer() 
    {
      super();
    }   
    
    private var _data:Object;
    
    [Inspectable(environment="none")]
    [Bindable("dataChange")]       
    
    /**
     * The <code>TickItem</code> that corresponds to this tick.
     * This value is assigned by the owning scale. You can use the value
     * to customize the drawing of the tick according to <code>TickItem</code>.
     * 
     * @see ilog.gauges.TickItem
     */    
    public function get data():Object
    {
      return _data;
    }
    
    /**
     * @private
     */
    public function set data(value:Object):void
    {
      _data = value;
      invalidateDisplayList();
      dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
    }    
    
    private function get valueRenderer():GaugeElement {
      if (parent == null)
        return null;
      var gauge:Object = UIComponent(parent.parent).owner;
      if (gauge == null)
        return null;
      return gauge.valueRenderer as GaugeElement;      
    }   
    
    /**
     * @private
     */
    protected override function updateDisplayList(unscaledWidth:Number, 
                                                  unscaledHeight:Number):void {

      var value:Number = NaN;
      var scale:IScale = TickItem(data).scale;
      var tickValue:Number = TickItem(data).value as Number;
      if (valueRenderer is RectangularValueRenderer) {
        var rvr:RectangularValueRenderer = valueRenderer as RectangularValueRenderer;
        if (rvr != null) {
          if (!isNaN(rvr.transitionPosition)) {
            value = IRectangularScale(scale).valueForPosition(rvr.transitionPosition) as Number;
          } else {
            value = rvr.value as Number;
          }
        }        
      } else {
        // circular
        var cvr:CircularValueRenderer = valueRenderer as CircularValueRenderer;
        if (cvr != null) {
          if (!isNaN(cvr.transitionAngle)) {
            value = ICircularScale(scale).valueForAngle(cvr.transitionAngle) as Number;
          } else {
            value = cvr.value as Number;
          }
        }           
      }

      graphics.clear();
      var opacity:Number = 0.15;
      var vmin:Number;
      var vmax:Number; 
      // first and last tick have specific behaviors
      if (data === scale.majorTickItems[0]) {
        vmin = tickValue;
        vmax = (scale.majorTickItems[1].value + tickValue) / 2;
      } else if (data === scale.majorTickItems[scale.majorTickItems.length - 1]) {
        vmin = (tickValue + scale.majorTickItems[scale.majorTickItems.length - 2].value) / 2;
        vmax = tickValue;
      } else {
        var i:int = scale.majorTickItems.indexOf(data, 1);
        // we are called with a tick item of another scale, this can happen
        // temporarily when switching scale
        if (i == -1)
          return;
        vmin = (tickValue + scale.majorTickItems[i - 1].value) / 2;
        vmax = (scale.majorTickItems[i + 1].value + tickValue) / 2;        
      }
      if (!isNaN(value)) {
        if (vmax < value) {
          opacity = 0.7;             
        } else if (vmin <= value && vmax >= value) {
          opacity = 0.55*(value - vmin) / (vmax - vmin) + 0.15;
        }
      }                  
      graphics.beginFill(0xffffff, opacity);
      graphics.lineStyle(3, 0x000000, opacity, true);             
      graphics.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 10, 10);
      graphics.endFill();
    }            
  }
}
